﻿namespace express.compiler;

public class Tokenizer
{
    private String exprString;
    private String currToken = "";
    private List<String> tokens = new List<string>();

    public Tokenizer(String exprString)
    {
        this.exprString = exprString;
    }

    public String GetAndRemoveKeyword(String keyword)
    {
        if (exprString.StartsWith(keyword))
        {
            exprString = exprString.Remove(0, keyword.Length);
            return keyword;
        }
        else
        {
            return null;
        }
    }

    public List<String> Tokenize()
    {
        String[] specKeywords = { "&&", "||", "&", "|", "+", "-", "*", "/", ">=", "<=", "<=", "=" };
        while (!string.IsNullOrEmpty(exprString))
        {
            foreach (string specKeyword in specKeywords)
            {
                String keyword = GetAndRemoveKeyword(specKeyword);
                if (keyword != null)
                {
                    if (!string.IsNullOrEmpty(this.currToken))
                    {
                        tokens.Add(this.currToken);
                        this.currToken = "";
                    }
                    tokens.Add(keyword);
                    break;
                }
            }

            String one = exprString.Substring(0, 1);
            exprString = exprString.Substring(1);

            //丢弃逗号
            if (string.Equals(one, ","))
            {
                if (!string.IsNullOrEmpty(currToken))
                {
                    this.tokens.Add(currToken);
                    this.currToken = "";
                }
                continue;
            }


            if (string.Equals(one, "(") || string.Equals(one, ")"))
            {
                if (!string.IsNullOrEmpty(currToken))
                {
                    this.tokens.Add(currToken);
                    this.currToken = "";
                }
                this.tokens.Add(one);
                continue;
            }

            if (string.Equals(one, Keywords.PARAM_START) || string.Equals(one, Keywords.PARAM_END))
            {
                if (!string.IsNullOrEmpty(currToken))
                {
                    this.tokens.Add(currToken);
                    this.currToken = "";
                }
                this.tokens.Add(one);
                continue;
            }

            if (string.Equals(one, " ") || string.Equals(one, "\n") || string.Equals(one, "\r"))
            {
                if (!string.IsNullOrEmpty(currToken))
                {
                    this.tokens.Add(currToken);
                    this.currToken = "";
                }
                continue;
            }

            this.currToken += one;
        }

        if (!string.IsNullOrEmpty(this.currToken))
        {
            this.tokens.Add(this.currToken);
        }

        return this.tokens;
    }
}